using System;
using System.Threading.Tasks;
using Phoenix.ActionResults;

namespace Phoenix.Framework
{
    public class ReflectedTaskActionDescriptor : ActionDescriptorBase
    {
        public ReflectedTaskActionDescriptor(
            MethodDescriptor methodDescriptor, 
            IControllerDescriptor controllerDescriptor) : 
            base(methodDescriptor, controllerDescriptor)
        {
        }

        public override Task<ActionResult> Execute(IController controller, ControllerActionContext controllerActionContext)
        {
            var tcs = new TaskCompletionSource<ActionResult>();

            var task = Invoke<Task>(controller, controllerActionContext);

            task.ContinueWith(t =>
            {
                if (t.IsFaulted)
                    tcs.SetException(t.Exception);
                else if (t.IsCanceled)
                    tcs.SetCanceled();
                else
                {
                    var actionResult = (ActionResult)t.GetType().GetProperty("Result").GetValue(t, null);
                    tcs.SetResult(actionResult);
                }
            });

            return tcs.Task;
        }
    }
}